/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *   gbx-emu - memory.h                                                    *
 *   gbx-emu homepage: http://code.google.com/p/gbx-emu/                   *
 *   Copyright (C) 2009 olejl77@gmail.com                                  *
 *                                                                         *
 *   This program is free software: you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation, either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the          *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef MEMORY_H
#define MEMORY_H
#include "common.h"

class Gameboy;
class Cpu;
class Log;
class Memory : public Common
{
friend class Gameboy;
friend class Cpu;
friend class DebuggerWidget;
private:
    Gameboy *_gb;
    Cpu *_cpu;
    Log *_log;

    u8 *memory;
    u8 *_cart;
    ROM_TYPES rom_type;

public:
    Memory(Gameboy *ptr);
    ~Memory();


/**
 * \fn const u8* getMemory()   const { return memory; }
 * Returns a pointer to the memory array. It is used by Cpu
 * to directly address the the internal memory for things
 * related to the Cpu and not to execution of the ROM
 * \return Pointer to the memory
**/
    const u8* getMemory()   const { return memory; }
/**
 * \fn void setCpu(Cpu *ptr) { _cpu = ptr; }
 * Sets the pointer to the Cpu class. Required for interactions between Memory and Cpu
 * \param ptr   Pointer to the Cpu class
**/
    void setCpu(Cpu *ptr) { _cpu = ptr; }
/**
 * \fn void setLog(Log *ptr) { _log = ptr; }
 * Sets the pointer to the Log class. Required for interactions between Memory and Log
 * \param ptr   Pointer to the Log class
**/
    void setLog(Log *ptr) { _log = ptr; }

    void write(u16 addr, u8 value);
    void write_word(u16 addr, u16 value);
    u8 read(u16 addr) const;
    u16 read_word(u16 addr);
    bool Load(u8 *cart, ROM_TYPES type);
};

/** 
 * An enum.
 * More detailed enum description.
*/
enum IO_REGISTERS {
    P1    = 0xff00, /**< Register for reading joy pad info and determining system type (R/W) */
    SB    = 0xff01, /**< Serial transfer data (R/W) */
    SC    = 0xff02, /**< SIO control (R/W) */
    DIV   = 0xff04, /**< Divider Register (R/W) */
    TIMA  = 0xff05, /**< Timer counter (R/W) */
    TMA   = 0xff06, /**< Timer Modulo (R/W) */
    TAC   = 0xff07, /**< Timer Control (R/W) */
    IF    = 0xff0f, /**< Interrupt Flag (R/W) */
    NR10  = 0xff10, /**< Sound Mode 1 register, Sweep register (R/W) */
    NR11  = 0xff11, /**< Sound Mode 1 register, Sound length/Wave pattern duty (R/W) */
    NR12  = 0xff12, /**< Sound Mode 1 register, Envelope (R/W) */
    NR13  = 0xff13, /**< Sound Mode 1 register, Frequency lo (W) */
    NR14  = 0xff14, /**< Sound Mode 1 register, Frequency hi (R/W) */
    NR21  = 0xff16, /**< Sound Mode 2 register, Sound Length; Wave Pattern Duty (R/W) Only bits 7-6 can be read. */
    NR22  = 0xff17, /**< Sound Mode 2 register, envelope (R/W) */
    NR23  = 0xff18, /**< Sound Mode 2 register, frequency lo data (W) */
    NR24  = 0xff19, /**< Sound Mode 2 register, frequency hi data (R/W) */
    NR30  = 0xff1a, /**< Sound Mode 3 register, Sound on/off (R/W) */
    NR31  = 0xff1b, /**< Sound Mode 3 register, sound length (R/W) */
    NR32  = 0xff1c, /**< Sound Mode 3 register, Select output level (R/W) */
    NR33  = 0xff1d, /**< Sound Mode 3 register, frequency's lower data (W) */
    NR34  = 0xff1e, /**< Sound Mode 3 register, frequency's higher data (R/W) */
    NR41  = 0xff20, /**< Sound Mode 4 register, sound length (R/W) */
    NR42  = 0xff21, /**< Sound Mode 4 register, envelope (R/W) */
    NR43  = 0xff22, /**< Sound Mode 4 register, polynomial counter (R/W) */
    NR44  = 0xff23, /**< Sound Mode 4 register, counter/consecutive; inital (R/W) */
    NR50  = 0xff24, /**< Channel control / ON-OFF / Volume (R/W) */
    NR51  = 0xff25, /**< Selection of Sound output terminal (R/W) */
    NR52  = 0xff26, /**< Sound on/off (R/W) */
    WPRAM = 0xff30, /**< Waveform storage for arbitrary sound data 0xff30 - 0xff3f */
    LCDC  = 0xff40, /**< LCD Control (R/W) */
    STAT  = 0xff41, /**< LCDC Status (R/W) */
    SCY   = 0xff42, /**< Scroll Y (R/W) */
    SCX   = 0xff43, /**< Scroll X (R/W) */
    LY    = 0xff44, /**< LCDC Y-Coordinate (R) */
    LYC   = 0xff45, /**< LY Compare (R/W) */
    DMA   = 0xff46, /**< DMA Transfer and Start Address (W) */
    BGP   = 0xff47, /**< BG & Window Palette Data (R/W) */
    OBP0  = 0xff48, /**< Object Palette 0 Data (R/W) */
    OBP1  = 0xff49, /**< Object Palette 1 Data (R/W) */
    WY    = 0xff4a, /**< Window Y Position (R/W) */
    WX    = 0xff4b, /**< Window X Position (R/W) */
    IE    = 0xffff, /**< Interrupt Enable (R/W) */
}; /**< enum variable. Details. */

// memory sizes
enum ROM_SIZES {
    ROM_B1_SIZE = 0x4000,
    ROM_B2_SIZE = 0x4000,
    VRAM_SIZE   = 0x2000,
    RAM_SIZE    = 0x4000,
    OAM_SIZE    = 0x00a0,
    EMPTY1_SIZE = 0x0060,
    IO_SIZE     = 0x004c,
    EMPTY2_SIZE = 0x0034,
    IEREG_SIZE  = 0x0080,
    WPRAM_SIZE  = 0x0080,
};
#endif // MEMORY_H
